#include <audio/MIDI/MIDIMusicDeviceMacOSX.h>

#if NE_PLATFORM == NE_PLATFORM_MACOSX

namespace ne
{
    MIDIMusicDeviceMacOSX::MIDIMusicDeviceMacOSX()
        : MIDIOutDevice(0, "MIDI Music Device MacOSX"),
          mGraph(0),
          mSynthUnit(0)
    {
        _create();
    }

    bool MIDIMusicDeviceMacOSX::open()
    {
        if (isOpen()) return true;

        NewAUGraph(&mGraph);

        AudioComponentDescription acd;
        acd.componentManufacturer = kAudioUnitManufacturer_Apple;
        acd.componentFlags = 0;
        acd.componentFlagsMask = 0;

        AUNode synthNode;
        acd.componentType = kAudioUnitType_MusicDevice;
        acd.componentSubType = kAudioUnitSubType_DLSSynth;
        AUGraphAddNode(mGraph, &acd, &synthNode);

        AUNode outNode;
        acd.componentType = kAudioUnitType_Output;
        acd.componentSubType = kAudioUnitSubType_DefaultOutput;
        AUGraphAddNode(mGraph, &acd, &outNode);

        AUGraphOpen(mGraph);
        AUGraphConnectNodeInput(mGraph, synthNode, 0, outNode, 0);
        AUGraphNodeInfo(mGraph, synthNode, 0, &mSynthUnit);
        AUGraphNodeInfo(mGraph, outNode, 0, &mOutUnit);

        AUGraphInitialize(mGraph);

        AUGraphStart(mGraph);

        CAShow(mGraph);

        mIsOpen = true;

        return true;
    }

    bool MIDIMusicDeviceMacOSX::reset()
    {
        return true;
    }

    bool MIDIMusicDeviceMacOSX::close()
    {
        if (!isOpen()) return true;

        if (mGraph == 0) return false;

        AUGraphStop(mGraph);
        DisposeAUGraph(mGraph);
        mIsOpen = false;
        return true;
    }

    bool MIDIMusicDeviceMacOSX::sendEvent(const byte event, const byte parameter1, const byte parameter2)
    {
        if (mSynthUnit == 0) return false;

        MusicDeviceMIDIEvent(mSynthUnit, event, parameter1, parameter2, 0);
        return true;
    }

    bool MIDIMusicDeviceMacOSX::sendSysExEvent(const byte *buffer, const uint32_t length)
    {
        if (mSynthUnit == 0) return false;

        MusicDeviceSysEx(mSynthUnit, buffer, length);
        return true;
    }

    MIDIMusicDeviceMacOSX::~MIDIMusicDeviceMacOSX()
    {
        _destroy();
    }

    
    bool MIDIMusicDeviceMacOSX::_create()
    {
        return true;
    }

    bool MIDIMusicDeviceMacOSX::_destroy()
    {
        return close();
    }
}

#endif
